package grpc

import (
	"context"
	"log"
	"time"

	"daxin.my/test-netserver/api"
	"daxin.my/test-netserver/protocol/grpc/helloworld"
	"google.golang.org/grpc"
)

type GrpcClient struct {
	client helloworld.GreeterClient
	conn   *grpc.ClientConn
	state  int32 // 当前发送消息状态， 0. 正常 1. 慢
}

func InitGrpcClient(address string) *GrpcClient {
	// Set up a connection to the server.
	conn, err := grpc.Dial(address, grpc.WithInsecure())
	if err != nil {
		panic(err)
	}
	client := helloworld.NewGreeterClient(conn)

	log.Printf("Start Grpc Client, address: %s\n", address)
	return &GrpcClient{
		client: client,
		conn:   conn,
		state:  0,
	}
}

func (c *GrpcClient) Request(param api.RequestParam) {
	ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
	defer cancel()

	startTime := time.Now()
	r, err := c.client.SayHello(
		ctx,
		&helloworld.HelloRequest{
			Sleep:        param.Sleep,
			ResponseByte: param.ResponseByteNum,
			Payload:      string(make([]byte, param.RequestByteNum)),
		})

	if err != nil {
		log.Printf("Grpc Client Failed: %v\n", err)
		return
	}
	duration := time.Since(startTime)
	log.Printf("Grpc Client Success. request size = %d, response size = %d, cost %dms",
		param.RequestByteNum, len(r.GetMessage()), duration.Milliseconds())
}

func (client *GrpcClient) Visit() {
	requestParam := api.RequestParam{
		Sleep:           0,
		StatusCode:      200,
		RequestByteNum:  10,
		ResponseByteNum: 10,
	}

	switch client.state {
	case 1:
		requestParam.Sleep = 500
		client.state = 0
	default:
		client.state = 1
	}
	client.Request(requestParam)
}

func (c *GrpcClient) Close() {
	_ = c.conn.Close()
}
